package com.raising.modules.code.controller;

import com.raising.StaticParam;
import com.raising.modules.code.config.Config;
import com.raising.modules.code.entity.*;
import com.raising.modules.code.service.CodePoolService;
import com.raising.modules.code.service.CodeProjectService;
import com.raising.modules.code.service.DbService;
import com.raising.modules.code.utils.StringUtils;
import com.raising.modules.code.utils.db.DBMangerPool;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.bind.annotation.*;

import com.raising.framework.controller.BaseController;
import com.raising.framework.entity.ResultVo;
import com.raising.framework.interceptor.Page;
import com.raising.modules.sys.utils.DictUtils;

import com.raising.utils.JStringUtils;

import com.raising.modules.code.service.CodeTemplateService;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 模板 控制器
 * @author gaoyuan
 * @createTime 2018-01-02 20:26:14
 */
@Controller
@RequestMapping("${adminPath}/code/codeTemplate")
public class CodeTemplateController extends BaseController {

    @Autowired
    private CodeTemplateService codeTemplateService;
    @Autowired
    private CodeProjectService codeProjectService;
    @Autowired
    private CodePoolService codePoolService;
    /**
     * 获取单个对象（共用）
     * @author gaoyuan
     * @createTime 2018-01-02 20:26:14
     */
    @ModelAttribute
    public CodeTemplate get(@RequestParam(required = false) String id) {
        CodeTemplate entity = null;
        if (JStringUtils.isNotBlank(id)) {
            entity = codeTemplateService.get(id);
        }
        if (entity == null) {
            entity = new CodeTemplate();
        }
        return entity;
    }

    /**
     * 加载单条模板内容
     * @author gaoyuan
     * @createTime 2018-01-02 20:26:14
     */
    @RequiresPermissions("code:codeTemplate:view")
    @RequestMapping(value = "/get.json", method = RequestMethod.POST)
    public @ResponseBody ResultVo get(Model model, String id) {
        return new ResultVo(ResultVo.SUCCESS,"ok",codeTemplateService.get(id));
    }

    /**
    * 跳转至列表页面
    * @author gaoyuan
    * @createTime 2018-01-02 20:26:14
    */
    @RequiresPermissions("code:codeTemplate:view")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Model model) {
        List<CodeProject> codeProjectlist = codeProjectService.getList(new CodeProject());
        model.addAttribute("codeProjectlist",codeProjectlist);

        CodeTemplate template = codeTemplateService.get("1");
        model.addAttribute("template",template);
        return "code/codeTemplate/list";
    }

    /**
    * 加载列表分页数据
    * @author gaoyuan
    * @createTime 2018-01-02 20:26:14
    */
    @RequiresPermissions("code:codeTemplate:view")
    @RequestMapping(value = "/getPage.json", method = RequestMethod.POST)
    public @ResponseBody ResultVo getPage(Model model, CodeTemplate codeTemplate,Page<CodeTemplate> page,String projectId) {
        codeTemplate.setProjectId(projectId);
        page.setEntity(codeTemplate);
        page.setOrderBy(" a.id asc ");
        return new ResultVo(ResultVo.SUCCESS,"ok",codeTemplateService.getPage(page));
    }

    /**
    * 跳转新增页面
    * @author gaoyuan
    * @createTime 2018-01-02 20:26:14
    */
    @RequiresPermissions("code:codeTemplate:create")
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public String create(CodeTemplate codeTemplate,Model model) {
        model.addAttribute("codeTemplate", codeTemplate);
        // 是否可用
        model.addAttribute("yn", DictUtils.getDictList("DIM_YN"));
        List<CodeProject> codeProjectlist = codeProjectService.getList(new CodeProject());
        model.addAttribute("codeProjectlist",codeProjectlist);
        return "code/codeTemplate/add";
    }

    /**
    * 执行新增操作
    * @author gaoyuan
    * @createTime 2018-01-02 20:26:14
    */
    @RequiresPermissions("code:codeTemplate:create")
    @RequestMapping(value = "/create.json", method = RequestMethod.POST)
    @ResponseBody
    public ResultVo create(String catalog,String name,String projectId, RedirectAttributes redirectAttributes) {
        if(name!=null){
            name = JStringUtils.trim(name);
        }
        if(!name.toLowerCase().endsWith(".ftl")){
            name = name + ".ftl";
        }
        CodeTemplate codeTemplate = new CodeTemplate();
        codeTemplate.setCatalog(catalog);
        codeTemplate.setName(name);
        codeTemplate.setProjectId(projectId);
        codeTemplate.setStatus(StaticParam.VALID_STRING);
        codeTemplate.setContent("");
        codeTemplate.setStartNum("0");
        codeTemplate.setSuccessNum("0");
        codeTemplate.setFailureNum("0");

        codeTemplateService.save(codeTemplate);
        addMessage(redirectAttributes,"新增成功");
        return new ResultVo(ResultVo.SUCCESS,ResultVo.CODE_OK,"成功","");
    }
    /**
    * 跳转更新页面
    * @author gaoyuan
    * @createTime 2018-01-02 20:26:14
    */
    @RequiresPermissions("code:codeTemplate:update")
    @RequestMapping(value = "/update", method = RequestMethod.GET)
    public String update(CodeTemplate codeTemplate, Model model) {
        model.addAttribute("codeTemplate", codeTemplate);
        // 是否可用
        model.addAttribute("yn", DictUtils.getDictList("DIM_YN"));
        return "code/codeTemplate/edit";
    }

    /**
     * 执行更新操作
     * @author gaoyuan
     * @createTime 2018-01-02 20:26:14
     */
    @RequiresPermissions("code:codeTemplate:update")
    @RequestMapping(value = "/update.json", method = RequestMethod.POST)
    @ResponseBody
    public ResultVo update(String id,String content) {
        //这里目前只更新content内容
        CodeTemplate codeTemplate = new CodeTemplate();
        codeTemplate.setId(id);
        codeTemplate.setContent(content);
        codeTemplateService.update(codeTemplate);
        return new ResultVo(ResultVo.SUCCESS,ResultVo.CODE_OK,"成功","1");
    }
    /**
    * 执行删除操作
    * @author gaoyuan
    * @createTime 2018-01-02 20:26:14
    */
    @RequiresPermissions("code:codeTemplate:delete")
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    public String delete(String id,int pageNo,int pageSize, RedirectAttributes redirectAttributes) {
        codeTemplateService.delete(id);
        addMessage(redirectAttributes,"删除成功");
        return "redirect:"+ adminPath +"/code/codeTemplate/list?pageNo="+pageNo+"&pageSize="+pageSize;
    }
    /**
     * 删除模板
     * @author GaoYuan
     * @datetime 2018/1/3 下午5:14
     */
    @RequiresPermissions("code:codeTemplate:delete")
    @RequestMapping(value = "/delete.json", method = RequestMethod.POST)
    @ResponseBody
    public ResultVo delete(String id) {
        codeTemplateService.delete(id);
        return new ResultVo(ResultVo.SUCCESS,ResultVo.CODE_OK,"成功","");
    }

    /**
     * 跳转代码生成页面
     * @author GaoYuan
     * @datetime 2018/1/4 下午2:05
     */
    @RequiresPermissions("code:codeTemplate:start")
    @RequestMapping(value = "/toStart", method = RequestMethod.GET)
    public String toStart(Model model) {
        // 是否可用
        model.addAttribute("yn", DictUtils.getDictList("DIM_YN"));
        //查询所有项目
        List<CodeProject> codeProjectlist = codeProjectService.getList(new CodeProject());
        model.addAttribute("codeProjectlist",codeProjectlist);
        //查询数据库连接池
        List<CodePool> codePoollist = codePoolService.getList(new CodePool());
        model.addAttribute("codePoollist",codePoollist);
        return "code/codeTemplate/start";
    }

    DbService dbService = new DbService();
    /** 操作池 */
    DBMangerPool dBMangerPool = DBMangerPool.getInstance();
    /**
     * 执行单个模板生成文件
     * @author GaoYuan
     * @datetime 2018/1/4 下午4:26
     */
    @RequiresPermissions("code:codeTemplate:start")
    @RequestMapping(value = "/startOne.json", method = RequestMethod.POST)
    @ResponseBody
    public ResultVo startOne(String outPath,String author,String chosenTableNm,String table,String templateId) throws Exception{
        String[] tableAndDesc = chosenTableNm.split("\\(");
        String tableDesc = tableAndDesc[1].split("\\)")[0];

        String[] tableAttr = table.split("-");
        //资源池标识
        String poolId = tableAttr[0];
        //数据库名称
        String databasenm = tableAttr[1];
        //表名
        String tablenm = tableAttr[2];

        /**1、获取模板相关内容*/
        CodeTemplate codeTemplate = codeTemplateService.get(templateId);
        /**2、获取资源池相关内容*/
        CodePool codePool = codePoolService.get(poolId);

        List<ColumnModel> columns = dBMangerPool.getDBManger(Config.dbKey).getColumnsByTable(databasenm, tablenm);
        String className = StringUtils.toClassName(tablenm);

//        codeTemplateService.insertStartOne(templateId,outPath,author,table,tableDesc);



        // 装载model数据
        TableModel tableModel = new TableModel();
        tableModel.setPackageName("");
        tableModel.setModel("sys");
        tableModel.setSubModel("");
        tableModel.setClassName(className);
        tableModel.setColumns(columns);
        tableModel.setTableDesc(tableDesc);
        tableModel.setTableName(table);
        tableModel.setAuthorNm(author);
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        tableModel.setCreateTime(df.format(new Date()));

        //代码存放路径
        String codePath = "src.main.java.";
        //sql文件存放路径
        String sqlPath = "src.main.resources.mappings.";
        //jsp文件存放路径
        String jspPath = "src.main.webapp.WEB-INF.view.";

        // 开始生成实体类
        String path = "src/main/java/com/raising";
        save(tableModel,codeTemplate.getContent(),codeTemplate.getName(),path);



        return new ResultVo(ResultVo.SUCCESS,ResultVo.CODE_OK,"成功","");
    }

    /**
     * 保存到文件
     *
     * @return
     * @throws Exception
     */
    public void save(TableModel tableModel, String content,String tempName,String path) throws Exception {
        //先将内容存储至临时文件夹
        File file = new File("/Users/gy/Downloads/out_temp/"+tempName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(content.getBytes());
        fos.flush();
        fos.close();


        // 装载model数据
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("model", tableModel);
        Configuration cfg = new Configuration();
        FileTemplateLoader loader = new FileTemplateLoader(new File("/Users/gy/Downloads/out_temp"));
        TemplateLoader[] fileloadders = {loader};
        MultiTemplateLoader fmtl = new MultiTemplateLoader(fileloadders);
        cfg.setTemplateLoader(fmtl);

        Template template = cfg.getTemplate(tempName);


        //设置编码
        template.setEncoding("UTF-8");
        // 创建生成类的存放路径
        FileUtils.forceMkdir(new File("/Users/gy/Downloads/out/"+path));
        File output = new File("/Users/gy/Downloads/out/"+path, "test.java");
        FileOutputStream fos2= new FileOutputStream(output);
        OutputStreamWriter osw =new OutputStreamWriter(fos2, "UTF-8");
        BufferedWriter bw =new BufferedWriter(osw, 1024);
        // 开始创建
        template.process(data, bw);
        fos2.close();
        osw.close();
        bw.close();


    }

}
